package controller;

import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.ChoiceQuestion;
import model.Paper;
import model.UserGroup;

import core.CurrentUser;
import core.PgSQL;
import core.Tool;
import core.View;


public class EditPaper extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static PgSQL db = PgSQL.getInstance(); 

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		CurrentUser user = new CurrentUser(request);
		int pid = Tool.intval(request.getParameter("pid"));
		if(pid <= 0){
			if(!user.getGroup().hasPermission(UserGroup.ADD_PAPER)){
				View.showMessage(request, response, "You have no permission to add a new paper.", "back");
				return;
			}
		}else{
			if(!user.getGroup().hasPermission(UserGroup.EDIT_PAPER)){
				View.showMessage(request, response, "You have no permission to edit any paper.", "back");
				return;
			}
		}
		
		Paper p = null;
		if(pid > 0){
			ResultSet rs = db.query("SELECT * FROM qz_paper WHERE pid=" + pid);
			try{
				if(rs.next()){
					p = Paper.fromDatabase(rs);
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}

		if(p != null){
			int add_qid = Tool.intval(request.getParameter("addqid"));
			if(add_qid > 0){
				db.update("INSERT INTO qz_papercontent (pid,qid) VALUES (" + pid + "," + add_qid + ")");
				if(request.getParameter("ajax") != null){
					View.showMessage(request, response, "The question has been successfully added.", "back");
				}
			}
			int remove_qid = Tool.intval(request.getParameter("removeqid"));
			if(remove_qid > 0){
				db.update("DELETE FROM qz_papercontent WHERE pid=" + pid + " AND qid=" + remove_qid);
				if(request.getParameter("ajax") != null){
					View.showMessage(request, response, "The question has been successfully removed.", "back");
				}
			}
			
			if(request.getParameter("updatescore") != null){
				ResultSet rs = db.query("SELECT COUNT(point) FROM qz_papercontent WHERE pid=" + pid);
				try{
					if(rs.next()){
						p.setTotalScore(rs.getInt(1));
						db.update("UPDATE qz_paper SET totalscore=" + p.getTotalScore() + " WHERE pid=" + pid);
					}
				}catch(SQLException e){
					e.printStackTrace();
				}
			}

		}else{
			p = new Paper();
			p.setTitle("");
		}
		
		LinkedList<ChoiceQuestion> qlist = new LinkedList<ChoiceQuestion>();
		HashMap<Integer, Integer> qpoint = new HashMap<Integer, Integer>();
		ResultSet rs = db.query("SELECT q.*,p.point FROM qz_papercontent p LEFT JOIN qz_choicequestion q ON q.qid=p.qid WHERE p.pid=" + pid);
		try{
			while(rs.next()){
				ChoiceQuestion q = ChoiceQuestion.fromDatabase(rs);
				qlist.add(q);
				qpoint.put(q.getQid(), rs.getInt(6));
			}
		}catch(SQLException e){
			e.printStackTrace();
		}
		
		request.setAttribute("paper", p);
		request.setAttribute("question[]", qlist.toArray(new ChoiceQuestion[0]));
		request.setAttribute("qpoint", qpoint);

		String keyword = request.getParameter("keyword");
		String extra_condition = "";
		if(keyword != null && !keyword.isEmpty()){
			extra_condition = " content LIKE '%" + keyword + "%' AND ";
		}
		
		int limit = 20;
		LinkedList<ChoiceQuestion> unadded_question = new LinkedList<ChoiceQuestion>();
		rs = db.query("SELECT * FROM qz_choicequestion WHERE " + extra_condition + " qid NOT IN (SELECT qid FROM qz_papercontent WHERE pid=" + pid + ") LIMIT " + limit);
		try{
			while(rs.next()){
				unadded_question.add(ChoiceQuestion.fromDatabase(rs));
			}
		}catch(SQLException e){
			e.printStackTrace();
		}
		
		request.setAttribute("unadded_question[]", unadded_question.toArray(new ChoiceQuestion[0]));
		
		View.show(request, response, "edit_paper");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//TODO Perhaps the permission control of doGet() and doPost() can be combined
		CurrentUser user = new CurrentUser(request);
		int pid = Tool.intval(request.getParameter("pid"));
		if(pid <= 0){
			if(!user.getGroup().hasPermission(UserGroup.ADD_PAPER)){
				View.showMessage(request, response, "You have no permission to add a new paper.", "back");
				return;
			}
		}else{
			if(!user.getGroup().hasPermission(UserGroup.EDIT_PAPER)){
				View.showMessage(request, response, "You have no permission to edit any paper.", "back");
				return;
			}
		}
		
		String title = request.getParameter("title");
		if(title == null || title.isEmpty()){
			View.showMessage(request, response, "You must fill in a title.", "back");
			return;
		}
		title = Tool.htmlspecialchars(title);
		
		int timeout = Tool.intval(request.getParameter("timeout"));
		timeout = timeout <= 0 ? 10 : timeout;

		if(pid <= 0){
			PreparedStatement ps = db.prepareStatement("INSERT INTO qz_paper (pid, title, timeout, authorid, questionnum) VALUES (nextval('pid'), ?, ?, ?, 0)");
			try{
				ps.setString(1, title);
				ps.setInt(2, timeout);
				ps.setInt(3, user.getUid());
				ps.executeUpdate();
			}catch(SQLException e){
				e.printStackTrace();
			}
	
			ResultSet rs = db.query("SELECT currval('pid')");
			try{
				if(rs.next()){
					int insert_id = rs.getInt(1);
					response.sendRedirect("EditPaper?pid=" + insert_id);
					return;
				}
			}catch(SQLException e){
				e.printStackTrace();
			}
		}else{
			int total_score = 0;
			Enumeration<String> params = request.getParameterNames();
			while(params.hasMoreElements()){
				String pa = params.nextElement();
				if(!pa.startsWith("qpoint[")){
					continue;
				}
				
				int qid = Tool.intval(pa.split("\\[")[1].split("]")[0]);
				int point = Tool.intval(request.getParameter(pa));
				total_score += point;
				db.update("UPDATE qz_papercontent SET point=" + point + " WHERE pid=" + pid + " AND qid=" + qid);
			}
			
			PreparedStatement ps = db.prepareStatement("UPDATE qz_paper SET title=?, timeout=?,totalscore=? WHERE pid=?");
			try{
				ps.setString(1, title);
				ps.setInt(2, timeout);
				ps.setInt(3, total_score);
				ps.setInt(4, pid);
				ps.executeUpdate();
			
				View.showMessage(request, response, "The paper has been succesffuly updated.", "refresh");
			
			}catch(SQLException e){
				e.printStackTrace();
			}
		}
	}
}
